package com.ttxs.generator.output.js;

import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.util.FileUtils;
import com.ttxs.generator.engine.CustomFreemarker;
import com.ttxs.generator.output.Output;
import com.ttxs.generator.util.Constants;
import com.ttxs.generator.util.PathUtils;
import com.ttxs.generator.util.TableInfoUtils;
import com.ttxs.generator.vo.FormBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.*;
import java.util.*;

@Slf4j
public class ApiPathIndex implements Output {

    /**
     * 输出导出api路径的index.js文件，输出路径为：src/api/${projectName}/${moduleName}/index.js
     * 注意：没有主键的表或复合主键的表不会定义变量
     *
     * @param templateEngine
     */
    @Override
    public void write(CustomFreemarker templateEngine) throws IOException {
        boolean hasModule = templateEngine.hasModule();
        FormBean formBean = templateEngine.formBean();
        String moduleName = formBean.getModuleName();
        ConfigBuilder config = templateEngine.getConfigBuilder();
        List<TableInfo> tableInfoList = config.getTableInfoList();

        String apiJsPath = PathUtils.get(PathUtils.Vue.api, formBean.getVueProjectPath());
        boolean staticRoute = formBean.isStaticRoute();
        boolean springCloud = formBean.isSpringCloud();
        String artifactId = formBean.getArtifactId();
        if (springCloud) {
            apiJsPath += File.separator + formBean.getPlatformName();
        }
        File apiExportJs = new File(apiJsPath + File.separator
                + artifactId + File.separator
                + (hasModule ? moduleName + File.separator : "")
                + "index.js");
        FileUtils.forceMkdirParent(apiExportJs);
        Map<String, Set<String>> fileContentMap = parseFile(apiExportJs);
        // 替换或追加需要定义和导出的变量
        tableInfoList.forEach(tableInfo -> {
            if (tableInfo.isHavePrimaryKey() && !TableInfoUtils.isCompositeKey(tableInfo)) {
                String entityName = StringUtils.uncapitalize(tableInfo.getEntityName());

                /*String lineContent = staticRoute
                        ? "const " + entityName + " = '/" + (hasModule ? moduleName + "/" : "") + entityName + "'"
                        : "const " + entityName + " = '/" + artifactId + "/" + (hasModule ? moduleName + "/" : "") + entityName + "'";*/
                String lineContent =  springCloud || !staticRoute ?
                        "const " + entityName + " = '/" +  artifactId + "/" + (hasModule ? moduleName + "/" : "") + entityName + "'":
                        "const " + entityName + " = '/" + (hasModule ? moduleName + "/" : "") + entityName + "'";
                fileContentMap.get(Constants.CONST).add(lineContent);
                fileContentMap.get(Constants.EXPORT).add(entityName);
            }
        });

        try (BufferedWriter out = new BufferedWriter(new FileWriter(apiExportJs))) {
            for (String line : fileContentMap.get(Constants.CONST)) {
                out.write(line + Constants.LINE_SEPARATOR);
            }
            out.write("export default {");
            StringBuilder builder = new StringBuilder();
            for (String var : fileContentMap.get(Constants.EXPORT)) {
                builder.append(var).append(",");
            }
            if (builder.lastIndexOf(",") > -1) {
                builder.setLength(builder.length() - 1);
            }
            out.write(builder.toString());
            out.write("}");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 读取前端api调用路径的JS文件
     * 把需要定义的变量名存储到CONST_KEY
     * 把需要导出的变量名存储到EXPORT_KEY
     *
     * @param apiPathFile
     * @return
     */
    private Map<String, Set<String>> parseFile(File apiPathFile) {
        Map<String, Set<String>> contentMap = new HashMap<>();
        contentMap.put(Constants.CONST, new TreeSet<>());
        contentMap.put(Constants.EXPORT, new TreeSet<>());
        if (apiPathFile.exists()) {
            try (BufferedReader in = new BufferedReader(new FileReader(apiPathFile))) {
                String line;
                while ((line = in.readLine()) != null) {
                    if (line.startsWith("export default")) {
                        String tempLine = line.substring(line.indexOf("{") + 1, line.lastIndexOf("}")).trim();
                        if (tempLine.length() > 0) {
                            String[] varNames = tempLine.split(",");
                            contentMap.get(Constants.EXPORT).addAll(Arrays.asList(varNames));
                        }
                    } else {
                        contentMap.get(Constants.CONST).add(line);
                    }
                }
            } catch (FileNotFoundException e) {
                log.error(e.getMessage(), e);
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        return contentMap;
    }
}
